package ScalaStudy.chapter07

object Test18_ComplexWordCount {
  def main(args: Array[String]): Unit = {


    //////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////  复杂wordCount案例  //////////////////////////////////
    /////////////////////////////////////////////////////////////////////////////////////////

    println("===============================================================")
    println("====================  题目：统计拆开后的字母  ======================")
    println("===============================================================")
    println(" ")

    val tupleList: List[(String, Int)] = List(
      ("hello", 1),
      ("hello world", 2),
      ("hello scala", 3),
      ("hello spark from scala", 1),
      ("hello flink from scala", 2)
    )

    println("====================  思路一：直接展开成普通版本  ======================")

    val newStringList:List[String] = tupleList.map(
      kv => {
        (kv._1.trim + " ") * kv._2       //相当于把键乘以对应的值，然后展开。
      }
    )
    println(newStringList)

    println("============  接下来操作与普通版本一致  =============")

    val wordCountList = newStringList
      .flatMap(_.split(" "))                          //首先用空格进行分词
      .groupBy(word => word)                                  //按单词进行分组
      .map(kv => (kv._1,kv._2.length))                        //统计出每个单词的个数
      .toList
      .sortBy(_._2)(Ordering[Int].reverse)
      .take(3)                                                 //取前3

    println(wordCountList)

    println(" ")
    println("====================  思路二：直接基于预统计的结果进行转换  ======================")

    println("=============  1、将字符串打散为单词，并结合对应的个数包装成二元组  ======>>>>>  实现List((hello,1), (hello,2))这种模样")

    val preCountList: List[(String, Int)] = tupleList.flatMap(
      tuple => {
        val strings: Array[String] = tuple._1.split(" ")           //把每一个word单独用空格隔开
        strings.map(word => (word, tuple._2))                            //拿出来之后跟后面的value分别进行组合
      }
    )
    println(preCountList)

    println("=============  2、对二元组按照单词进行分组  ===============>>>>>>>>  实现scala -> List((scala,3), (scala,1), (scala,2))这种模样")

    val preCountMap:Map[String,List[(String,Int)]] = preCountList.groupBy(_._1)
    println(preCountMap)

    println("=============  3、 叠加每个单词预统计的个数值  ========>>>>>>>> List((scala,3), (scala,1), (scala,2))变成 scala -> 3+1+2这种模样")

    val countMap:Map[String, Int] = preCountMap.mapValues(      //mapValues是指对value进行操作
      tupleList => tupleList.map(_._2).sum                      //相当于对scala -> List((scala,3), (scala,1), (scala,2))变成 scala -> 3+1+2
    )
    println(countMap)

    println("=============  4、 转换成list，排序取前3  ========>>>>>>>> List((scala,3), (scala,1), (scala,2))变成 scala -> 3+1+2这种模样")

    val countList = countMap.toList   //转换成列表
      .sortWith(_._2 > _._2)          //根据value进行排序
      .take(3)                        //取前三

    println(countList)








  }
}
